package ejb;

import java.util.Collection;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import utils.ZaraException;

import entidadesBD.*;
import entidadesVO.*;

public @Stateless class AdministradorOFADBean implements AdministradorOFAD {

	@PersistenceContext(unitName="zara")
	private EntityManager manager;

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void setOFAD(OFADVO ofadVO) throws ZaraException{
		
		
		try{
			checkOFADExistance(ofadVO);
		}catch(ZaraException e1){
			throw new ZaraException(e1.toString());
		}
		
		OFAD ofad = new OFAD();
		manager.persist(ofad);
		
		Object[] articulosOFADList = ofadVO.getArticulosOFAD().toArray();
		
		for (int i = 0; i < articulosOFADList.length; i++ ){
			
			Query query = manager.createQuery("SELECT a FROM Articulo a WHERE a.referencia LIKE :referencia");
			query.setParameter("referencia", ((ArticulosOFADVO)articulosOFADList[i]).getArticulo().getReferencia());
				
			Articulo articulo = null;
			
			try{
				articulo = (Articulo)query.getSingleResult();
			}catch (NonUniqueResultException e2){
				
				manager.remove(ofad);
				
				throw new ZaraException(e2.toString());
			}finally{
				if(articulo != null){
					articulo.setNuevo(0);
					
					try{
						manager.merge(articulo);
						
						ArticulosOFAD articulosOFAD = new ArticulosOFAD();
						articulosOFAD.setArticulosOFADVO((ArticulosOFADVO)articulosOFADList[i]);
						
						articulosOFAD.setArticulo(articulo);
						articulosOFAD.setOfad(ofad);
						ofad.addArticulosOFAD(articulosOFAD);
					}catch (Exception e3){
						throw new ZaraException("No se pudo guardar el Articulo cuya referencia es:" + articulo.getReferencia());
					}
				}else{
					
					manager.remove(ofad);
					
					throw new ZaraException("No existe un Articulo para la referencia: " + ((ArticulosOFADVO)articulosOFADList[i]).getArticulo().getReferencia());
				}
			}
		}
		
		ofad.setOFADVO(ofadVO);
		try{
			manager.merge(ofad);
		}catch (Exception e){
			
			manager.remove(ofad);
			
			throw new ZaraException("No se pudo guardar la OFAD " + e.toString());
		}
	}
	
	public void setOFADS(Collection<OFADVO> ofads) throws ZaraException{
			
		Object[] ofadsArray = ofads.toArray();
		
		for (int i = 0; i < ofadsArray.length; i++){
			setOFAD((OFADVO)ofadsArray[i]);
		}
	}
	
	@SuppressWarnings("finally")
	private boolean checkOFADExistance(OFADVO ofadVO) throws ZaraException{
		
		Query query = manager.createQuery("SELECT o FROM OFAD o WHERE o.fechaOFAD LIKE :fechaOFAD");
		query.setParameter("fechaOFAD", ofadVO.getFechaOFAD());
						
		OFAD ofad = null;
					
		try{
			ofad = (OFAD)query.getSingleResult();
		}catch (NonUniqueResultException e){
			if (ofad == null){
				return true;
			}else{
				
				boolean ret = false;
				
				Object[] ofads = query.getResultList().toArray();
					
				for (int i = 0; i < ofads.length; i++){
					
					ofad = (OFAD)ofads[i];
					
					try{
						ret = compareOFADS(ofadVO, ofad);
					}catch(ZaraException e1){
						throw new ZaraException(e1.toString());
					}
				}
				
				if (ret == true){
					return true;
				}
			}
		}finally{
			try{
				if (ofad == null){
					return true;
				}else{
					return compareOFADS(ofadVO, ofad);
				}
			}catch(ZaraException e1){
				throw new ZaraException(e1.toString());
			}
		}
	}
	
	private boolean compareOFADS(OFADVO ofadVO, OFAD ofad) throws ZaraException{
		
		Object[] articulosOFADVOList = ofadVO.getArticulosOFAD().toArray();
		
		for (int i = 0; i < articulosOFADVOList.length; i++){
		
			boolean ret = true;
			
			Object[] articulosOFADList = ofad.getArticulosOFAD().toArray();
			
			for (int j = 0; j < articulosOFADList.length; j++){
				if (((ArticulosOFADVO)articulosOFADVOList[i]).getArticulo().getReferencia().equals(((ArticulosOFAD)articulosOFADList[j]).getArticulo().getReferencia())){
					if(((ArticulosOFADVO)articulosOFADVOList[i]).getPrecioFinal() == ((ArticulosOFAD)articulosOFADList[j]).getPrecioFinal()){
						ret = false;
					}
				}
			}
			
			if (ret){
				return true;
			}
		}
		
		throw new ZaraException("Hay una OFAD generada para el dia: " + ofadVO.getFechaOFAD() + " con iguales articulos a los suministrados");
	}
}

